/**
 * echarts图表类：事件河流图
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author clmtulip  (车丽美, clmtulip@gmail.com)
 *
 */


var ChartBase = require('./base');
var eventRiverLayout = require('../layout/eventRiver');
// 图形依赖
var PolygonShape = require('zrender/shape/Polygon');
// 组件依赖
require('../component/axis');
require('../component/grid');
require('../component/dataZoom');
var ecConfig = require('../config');
// 事件河流图默认参数
ecConfig.eventRiver = {
    zlevel: 0,
    // 一级层叠
    z: 2,
    // 二级层叠
    clickable: true,
    legendHoverLink: true,
    itemStyle: {
        normal: {
            // color: 各异,
            borderColor: 'rgba(0,0,0,0)',
            borderWidth: 1,
            label: {
                show: true,
                position: 'inside',
                // 可选为'left'|'right'|'top'|'bottom'
                formatter: '{b}'    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
            }
        },
        emphasis: {
            // color: 各异,
            borderColor: 'rgba(0,0,0,0)',
            borderWidth: 1,
            label: { show: true }
        }
    }
};
var ecData = require('../util/ecData');
var ecDate = require('../util/date');
var zrUtil = require('zrender/tool/util');
var zrColor = require('zrender/tool/color');
/**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 数据
     * @param {Object} component 组件
     */
function EventRiver(ecTheme, messageCenter, zr, option, myChart) {
    // 图表基类
    ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
    var self = this;
    self._ondragend = function () {
        self.isDragend = true;
    };
    this.refresh(option);
}
EventRiver.prototype = {
    type: ecConfig.CHART_TYPE_EVENTRIVER,
    _buildShape: function () {
        var series = this.series;
        this.selectedMap = {};
        // 数据预处理
        this._dataPreprocessing();
        var legend = this.component.legend;
        // 调用布局算法计算事件在Y轴上的位置
        var eventRiverSeries = [];
        for (var i = 0; i < series.length; i++) {
            if (series[i].type === this.type) {
                series[i] = this.reformOption(series[i]);
                this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
                var serieName = series[i].name || '';
                // 系列图例开关
                this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;
                if (!this.selectedMap[serieName]) {
                    continue;
                }
                this.buildMark(i);
                eventRiverSeries.push(this.series[i]);
            }
        }
        eventRiverLayout(eventRiverSeries, this._intervalX, this.component.grid.getArea());
        // 绘制事件河
        this._drawEventRiver();
        this.addShapeList();
    },
    /**
          * 处理数据
          */
    _dataPreprocessing: function () {
        // 将年月日的时间转化为平面坐标
        var series = this.series;
        var xAxis;
        var evolutionList;
        for (var i = 0, iLen = series.length; i < iLen; i++) {
            if (series[i].type === this.type) {
                xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex || 0);
                for (var j = 0, jLen = series[i].data.length; j < jLen; j++) {
                    evolutionList = series[i].data[j].evolution;
                    for (var k = 0, kLen = evolutionList.length; k < kLen; k++) {
                        evolutionList[k].timeScale = xAxis.getCoord(ecDate.getNewDate(evolutionList[k].time) - 0);
                        // evolutionList[k].valueScale = evolutionList[k].value;
                        // modified by limei.che, to normalize the value range
                        evolutionList[k].valueScale = Math.pow(evolutionList[k].value, 0.8);
                    }
                }
            }
        }
        // 尾迹长度
        this._intervalX = Math.round(this.component.grid.getWidth() / 40);
    },
    /**
          * 绘制事件河流
          */
    _drawEventRiver: function () {
        var series = this.series;
        for (var i = 0; i < series.length; i++) {
            var serieName = series[i].name || '';
            if (series[i].type === this.type && this.selectedMap[serieName]) {
                for (var j = 0; j < series[i].data.length; j++) {
                    this._drawEventBubble(series[i].data[j], i, j);
                }
            }
        }
    },
    /**
          * 绘制气泡图
          */
    _drawEventBubble: function (oneEvent, seriesIndex, dataIndex) {
        var series = this.series;
        var serie = series[seriesIndex];
        var serieName = serie.name || '';
        var data = serie.data[dataIndex];
        var queryTarget = [
            data,
            serie
        ];
        var legend = this.component.legend;
        var defaultColor = legend ? legend.getColor(serieName) : this.zr.getColor(seriesIndex);
        // 多级控制
        var normal = this.deepMerge(queryTarget, 'itemStyle.normal') || {};
        var emphasis = this.deepMerge(queryTarget, 'itemStyle.emphasis') || {};
        var normalColor = this.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || defaultColor;
        var emphasisColor = this.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data) || (typeof normalColor === 'string' ? zrColor.lift(normalColor, -0.2) : normalColor);
        var pts = this._calculateControlPoints(oneEvent);
        var eventBubbleShape = {
            zlevel: serie.zlevel,
            z: serie.z,
            clickable: this.deepQuery(queryTarget, 'clickable'),
            style: {
                pointList: pts,
                smooth: 'spline',
                brushType: 'both',
                lineJoin: 'round',
                color: normalColor,
                lineWidth: normal.borderWidth,
                strokeColor: normal.borderColor
            },
            highlightStyle: {
                color: emphasisColor,
                lineWidth: emphasis.borderWidth,
                strokeColor: emphasis.borderColor
            },
            draggable: 'vertical',
            ondragend: this._ondragend
        };
        eventBubbleShape = new PolygonShape(eventBubbleShape);
        this.addLabel(eventBubbleShape, serie, data, oneEvent.name);
        ecData.pack(eventBubbleShape, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name);
        this.shapeList.push(eventBubbleShape);
    },
    /**
         * 根据时间-热度，计算气泡形状的控制点
         */
    _calculateControlPoints: function (oneEvent) {
        var intervalX = this._intervalX;
        var posY = oneEvent.y;
        var evolution = oneEvent.evolution;
        var n = evolution.length;
        if (n < 1) {
            return;
        }
        var time = [];
        var value = [];
        for (var i = 0; i < n; i++) {
            time.push(evolution[i].timeScale);
            value.push(evolution[i].valueScale);
        }
        var pts = [];
        // 从左向右绘制气泡的上半部分控制点
        // 第一个矩形的左端点
        pts.push([
            time[0],
            posY
        ]);
        // 从一个矩形 到 倒数第二个矩形 上半部分的中点
        var i = 0;
        for (i = 0; i < n - 1; i++) {
            pts.push([
                (time[i] + time[i + 1]) / 2,
                value[i] / -2 + posY
            ]);
        }
        // 最后一个矩形上半部分的中点
        pts.push([
            (time[i] + (time[i] + intervalX)) / 2,
            value[i] / -2 + posY
        ]);
        // 最后一个矩形的右端点
        pts.push([
            time[i] + intervalX,
            posY
        ]);
        // 从右向左绘制气泡的下半部分控制点
        // 最后一个矩形下半部分的中点
        pts.push([
            (time[i] + (time[i] + intervalX)) / 2,
            value[i] / 2 + posY
        ]);
        // 从倒数第二个矩形 到 一个矩形 下半部分的中点，由于polygon是闭合的，故不需要再加入左端点
        for (i = n - 1; i > 0; i--) {
            pts.push([
                (time[i] + time[i - 1]) / 2,
                value[i - 1] / 2 + posY
            ]);
        }
        return pts;
    },
    /**
         * 数据项被拖拽出去
         */
    ondragend: function (param, status) {
        if (!this.isDragend || !param.target) {
            // 没有在当前实例上发生拖拽行为则直接返回
            return;
        }
        // 别status = {}赋值啊！！
        status.dragOut = true;
        status.dragIn = true;
        status.needRefresh = false;
        // 会有消息触发fresh，不用再刷一遍
        // 处理完拖拽事件后复位
        this.isDragend = false;
    },
    /**
         * 刷新
         */
    refresh: function (newOption) {
        if (newOption) {
            this.option = newOption;
            this.series = newOption.series;
        }
        this.backupShapeList();
        this._buildShape();
    }
};
zrUtil.inherits(EventRiver, ChartBase);
// 图表注册
require('../chart').define('eventRiver', EventRiver);
module.exports = EventRiver || module.exports;;